/*
    Copyright (C) 2009, 2010, 2011, 2012 Daniel Gutson, Martin Gioiosa,
    Lucas Paradisi, Leonardo Boquillon and Hugo Arregui, FuDePAN

    This file is part of Biopp.

    Aso is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Biopp is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Biopp.  If not, see <http://www.gnu.org/licenses/>.

    NOTE: This file is in prototype stage, and is under active development.
*/

#ifndef BIO_TRIPLETS_INLINE_H
#error Internal header file, DO NOT include this.
#endif

#include <sstream>

namespace biopp
{

template<typename NucleotideClass>
TripletBase<NucleotideClass>& TripletBase<NucleotideClass>::operator=(const TripletBase<NucleotideClass>& other)
{
    triplet = other.triplet;
    return *this;
}

template<typename NucleotideClass>
bool TripletBase<NucleotideClass>::operator==(const TripletBase<NucleotideClass>& other) const
{
    return  triplet[0] == other.triplet[0] &&
            triplet[1] == other.triplet[1] &&
            triplet[2] == other.triplet[2];
}

template<typename NucleotideClass>
bool TripletBase<NucleotideClass>::operator<(const TripletBase<NucleotideClass>& other) const
{
    return  triplet[0] < other.triplet[0] ||
            (triplet[0] == other.triplet[0] &&
             ((triplet[1] < other.triplet[1] ||
               (triplet[1] == other.triplet[1] &&
                triplet[2] < other.triplet[2]))));
}

template<typename NucleotideClass>
NucleotideClass TripletBase<NucleotideClass>::operator[](size_t index) const
{
    return triplet[index];
}

template<typename NucleotideClass>
NucleotideClass& TripletBase<NucleotideClass>::operator[](size_t index)
{
    return triplet[index];
}

template<typename NucleotideClass>
bool TripletBase<NucleotideClass>::contains(NucleotideClass n) const
{
    return  triplet[0] == n ||
            triplet[1] == n ||
            triplet[2] == n;
}

template<typename NucleotideClass>
size_t TripletBase<NucleotideClass>::distance(const TripletBase<NucleotideClass>& other) const
{
    return (triplet[0] != other.triplet[0] ? 1 : 0) +
           (triplet[1] != other.triplet[1] ? 1 : 0) +
           (triplet[2] != other.triplet[2] ? 1 : 0);
}

template<typename NucleotideClass>
string TripletBase<NucleotideClass>::to_string() const
{
    std::stringstream stream;
    stream << triplet[0].as_char() << triplet[1].as_char() << triplet[2].as_char();
    return stream.str();
}

bool Triplet::isStop() const
{
    return translate() == Aminoacid(Aminoacid::STOP_CODON);
}

Aminoacid Triplet::translate() const
{
    return GeneticCode::translate(*this);
}

bool Triplet::isSibling(const Triplet& other) const
{
    return translate() == other.translate();
}

}
